package com.yc.navy.dayfresh.controller;

import com.yc.navy.dayfresh.dto.Result;
import com.yc.navy.dayfresh.entity.User;
import com.yc.navy.dayfresh.util.QRCodeUtil;
import com.yc.starter.login.config.LoginProperties;
import com.yc.starter.login.web.LoginAction;
import lombok.Data;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.SessionAttribute;

import javax.servlet.http.HttpSession;
import javax.websocket.OnClose;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.io.OutputStream;
import java.io.Serializable;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit;

/**
 * @author navy
 * @company 源辰信息
 * @date 2024/9/18
 * @email haijunzhou@hnit.edu.cn
 */
@RestController
@ServerEndpoint("/scanLogin/{token}")
public class ScanLoginDo {

    @Value("${myip:192.168.1.117}")
    String myip;
    @Value("${logo:d:/fruit.jpg}")
    String logo;
    @RequestMapping(path = "createMobileHtml",
        produces = MediaType.IMAGE_JPEG_VALUE)
    public void createMobileHtml(OutputStream out) throws Exception {
        String url = "http://"+myip+"/mobile.html";
        QRCodeUtil.encode(url,logo,out, true);
    }

    @Autowired
    RedisTemplate redisTemplate;

    // 创建PC端登录二维码
    @RequestMapping(path = "createLoginQrcode",
            produces = MediaType.IMAGE_JPEG_VALUE)
    public void createLoginQrcode(OutputStream out, HttpSession session) throws Exception {
        String token = UUID.randomUUID().toString();
        LoginInfo li = new LoginInfo();
        redisTemplate.opsForValue().set(token, li, 1, TimeUnit.MINUTES);
        String url = "http://" + myip + "/scanLoginQrcode?token=" + token;
        QRCodeUtil.encode(url,"d:/fruit.jpg",out, true);
        // 在生成二维的同时, 将token存入会话
        session.setAttribute("scanLoginToken", token);
        System.out.println("createLoginQrcode === " + token);
    }

    @Autowired
    LoginProperties loginProperties;
    // 手机扫码方法
    @RequestMapping("scanLoginQrcode")
    public Result scanLoginQrcode(String token, HttpSession session) throws IOException {
        System.out.println("scanLoginQrcode === " + token);
        User user = (User) session.getAttribute(loginProperties.getSessionKey());
        if(user == null){
            return new Result(-1, "请先登录系统", null);
        }
        LoginInfo li = (LoginInfo) redisTemplate.opsForValue().get(token);
        if(li == null){
            return new Result(-2, "二维码已经失效, 请刷新后重扫!", null);
        }
        if(li.status.equals("已扫码")){
            return new Result(-3, "该二维码已经扫码过了!", null);
        }
        li.setUser(user);
        li.setStatus("已扫码");
        redisTemplate.opsForValue().set(token, li);
        // 如何通知瀏覽器掃碼成功, 更新狀態
        Session wsSession = sessionMap.get(token);
        wsSession.getBasicRemote().sendText("ok");
        return new Result(1,"扫描成功!", null);
    }

    @RequestMapping("scanLogin")
    public Result scanLogin(String token, HttpSession session){
        System.out.println("scanLogin === " + token);
        LoginInfo li = (LoginInfo) redisTemplate.opsForValue().get(token);
        if(li == null){
            return new Result(-1, "二维码已失效!", null);
        }
        User user = li.getUser();
        session.setAttribute(loginProperties.getSessionKey(), user);
        redisTemplate.delete(token);
        return new Result(1, "登录成功!", user);
    }

    @RequestMapping("getScanLoginToken")
    public Result getScanLoginToken(
            @SessionAttribute(value = "scanLoginToken", required = false) String token){
        System.out.println("getScanLoginToken === " + token);
        if (token == null){
            return new Result(-1, "二维码已失效!", null);
        }
        return new Result(1, "登录token", token);
    }

    ///////////////////////////////////////////////////////////////

    static Map<String,Session> sessionMap = new ConcurrentHashMap<>();

    @OnOpen
    public void onOpen(Session session,
                       @PathParam("token") String token){
        sessionMap.put(token, session);
        session.getUserProperties().put("token",token);
    }

    @OnClose
    public void onClose(Session session){
        String token = (String) session.getUserProperties().get("token");
        sessionMap.remove(token);
    }

}

@Data
class LoginInfo implements Serializable {
    String status = "未扫码";
    User user;
}